介绍
1. redis 主从复制的问题
- Redis主从复制可将主节点数据同步给从节点,从节点此时有两个作用:
- 一旦主节点宕机,从节点作为主节点的备份可以随时顶上来
- 扩展主节点的读能力,分担主节点读压力
- 但是问题是:
- 一旦主节点宕机,从节点上位,那么需要人为修改所有应用方的主节点地址(改为新的master地址),还需要命令所有从节点复制新的主节点
- 那么这个问题,redis-sentinel就可以解决了
2. redis-sentinel 的介绍
- redis-sentinel 是 redis 官方推荐的高可用性解决方案
- 当用 redis 作 master(主)-slave(从) 的主从复制的时候,如果 master(主) 本身宕机,redis本身或者客户端都没有实现主从切换的功能
- 而 redis-sentinel 就是一个独立运行的进程,用于监控多个 master(主)-slave(从) 集群,自动发现 master(主) 宕机,进行自动切换将某一个 slave(从) 设置为 master(主)
- redis-sentinel只是redis的一个进程,它不存储数据,只用于监控 redis 的状态
- redis-sentinel 可以创建多个 sentinel(哨兵) 进行监控
- redis-sentinel 的默认端: 26379
3. sentinel(哨兵) 的主要功能
- 监控 redis 是否良好运行,每个一秒中向 master(主)节点 或 slave(从)节点 发送一个ping的命令查看这些节点是否能ping通
- 如果发现 master(主)节点 ping 不通,那么 sentinel(哨兵) 就会和其他 sentinel(哨兵) 进行 “协商” 选择某一个 slave(从)节点 作为 master(主)节点
- 当 sentinel(哨兵) 进行过主从切换后,主redis配置文件、从redis配置文件、sentinel(哨兵)配置文件 都会发生变化,即: 原本的 主redis配置文件 中会多一行 slaveof 配置项,sentinel(哨兵)配置文件的监控目标也随之改变
4. sentinel(哨兵) 是如何发现其他 sentinel(哨兵) 的
- sentinel 会通过命令连接向被监视的主从服务器发送 "Hello" 信息,该信息包含了 sentinel 的 ip、端口、id 等内容,以此来向其他 sentinel 宣告自己的存在。与此同时 sentinel 会通过订阅连接接收其他 sentinel 的 "Hello" 信息,以此来发现监视同一个主服务器的其他 sentinel

- sentinel 通过发送 "Hello" 信息来让 sentinel2 和 sentinel3 发现自己,其他两个 sentinel 也会进行类似的操作
5. redis-sentinel 的架构图




环境的准备
- 配置主从复制 -> 一主两从
1. 创建 redis-sentinel 文件夹
- 创建文件夹 /opt/redis-4.0.10/my_redis_sentinel -> 用于存放 sentinel(哨兵)配置 和 redis 配置文件,方便管理
mkdir /opt/redis-4.0.10/my_redis_sentinel
2. 配置主redis(master)
- 创建 主redis 配置文件 -> redis-6380.conf
touch /opt/redis-4.0.10/my_redis_sentinel/redis-6380.conf
- 修改 主redis 配置文件 -> redis-6380.conf
- 进入配置文件
vim /opt/redis-4.0.10/my_redis_sentinel/redis-6380.conf
- 修改配置文件
# 绑定远程连接ip,如需要远程访问当前服务器的redis(即: 让别人连接你的redis),那么就需要填写当前服务器的ip -> 0.0.0.0 代表 127.0.0.1 也代表 当前服务器ip
bind 0.0.0.0
# redis 端口
port 6380
# 是否后台运行 redis,在执行 redis-server redis.conf 命令时,如果为 yes 那么就不进入阻塞状态(即: 还可以输入其他命令),如果为 no 进入阻塞状态 (即: 无法输入别的命令)
daemonize yes
# 日志文件,注意: /data/6380/ 目录必须存在(即: 如果没有就需要手动创建)
logfile "/data/6380/redis.log"
# 配置 redis 的数据存放文件夹,一般存放redis的持久化存储文件和redis的日志文件等,注意: /data/6380/ 目录必须存在(即: 如果没有就需要手动创建)
dir /data/6380
# 定义 RDB 持久化文件名
dbfilename dump-6380.rdb
- 创建reids配置文件所需要的文件夹
mkdir /data/6380
3. 配置从redis1(slave1)
- 创建 从redis 配置文件 -> redis-6381.conf
touch /opt/redis-4.0.10/my_redis_sentinel/redis-6381.conf
- 修改 从redis 配置文件 -> redis-6381.conf
- 进入配置文件
vim /opt/redis-4.0.10/my_redis_sentinel/redis-6381.conf
- 修改配置文件
# 绑定远程连接ip,如需要远程访问当前服务器的redis(即: 让别人连接你的redis),那么就需要填写当前服务器的ip -> 0.0.0.0 代表 127.0.0.1 也代表 当前服务器ip
bind 0.0.0.0
# redis 端口
port 6381
# 是否后台运行 redis,在执行 redis-server redis.conf 命令时,如果为 yes 那么就不进入阻塞状态(即: 还可以输入其他命令),如果为 no 进入阻塞状态 (即: 无法输入别的命令)
daemonize yes
# 日志文件,注意: /data/6381/ 目录必须存在(即: 如果没有就需要手动创建)
logfile "/data/6381/redis.log"
# 配置 redis 的数据存放文件夹,一般存放redis的持久化存储文件和redis的日志文件等,注意: /data/6381/ 目录必须存在(即: 如果没有就需要手动创建)
dir /data/6381
# 定义 RDB 持久化文件名
dbfilename dump-6381.rdb
# 将 6380 redis 设置为当前的 6381 redis 的 主redis
slaveof 127.0.0.1 6380
- 创建reids配置文件所需要的文件夹
mkdir /data/6381
3. 配置从redis2(slave2)
- 创建 从redis 配置文件 -> redis-6382.conf
touch /opt/redis-4.0.10/my_redis_sentinel/redis-6382.conf
- 修改 从redis 配置文件 -> redis-6382.conf
- 进入配置文件
vim /opt/redis-4.0.10/my_redis_sentinel/redis-6382.conf
- 修改配置文件
# 绑定远程连接ip,如需要远程访问当前服务器的redis(即: 让别人连接你的redis),那么就需要填写当前服务器的ip -> 0.0.0.0 代表 127.0.0.1 也代表 当前服务器ip
bind 0.0.0.0
# redis 端口
port 6382
# 是否后台运行 redis,在执行 redis-server redis.conf 命令时,如果为 yes 那么就不进入阻塞状态(即: 还可以输入其他命令),如果为 no 进入阻塞状态 (即: 无法输入别的命令)
daemonize yes
# 日志文件,注意: /data/6382/ 目录必须存在(即: 如果没有就需要手动创建)
logfile "/data/6382/redis.log"
# 配置 redis 的数据存放文件夹,一般存放redis的持久化存储文件和redis的日志文件等,注意: /data/6382/ 目录必须存在(即: 如果没有就需要手动创建)
dir /data/6382
# 定义 RDB 持久化文件名
dbfilename dump-6382.rdb
# 将 6380 redis 设置为当前的 6382 redis 的 主redis
slaveof 127.0.0.1 6380
- 创建reids配置文件所需要的文件夹
mkdir /data/6382
4. 启动所有redis
redis-server /opt/redis-4.0.10/my_redis_sentinel/redis-6380.conf
redis-server /opt/redis-4.0.10/my_redis_sentinel/redis-6381.conf
redis-server /opt/redis-4.0.10/my_redis_sentinel/redis-6382.conf
5. 查看 redis 是否启动
ps -ef | grep redis

6. 查看 redis 是否能 ping 通
[root@kevin_linux /data 07:43:04]# redis-cli -h 10.0.0.3 -p 6380
10.0.0.3:6380> ping
PONG
[root@kevin_linux /data 07:43:39]# redis-cli -h 10.0.0.3 -p 6381
10.0.0.3:6381> ping
PONG
[root@kevin_linux /data 07:43:56]# redis-cli -h 10.0.0.3 -p 6382
10.0.0.3:6382> ping
PONG
7. 查看 redis 的主从身份状态
redis-cli -p 6380 info replication

redis-cli -p 6381 info replication

redis-cli -p 6382 info replication

7. 在 主redis(master) 写入数据,在 从redis(slave) 查看数据

redis-sentinel 的配置
- 注意:
- redis-sentinel只是redis的一个进程,它不存储数据,只用于监控 redis 的状态
- sentinel 默认端口号 26379
- 可以创建多个 sentinel(哨兵) 进行监控
1. 创建 sentinel 配置文件
- 创建三个 sentinel 配置文件到 /opt/redis-4.0.10/my_redis_sentinel 目录下
touch /opt/redis-4.0.10/my_redis_sentinel/sentinel-26380.conf
touch /opt/redis-4.0.10/my_redis_sentinel/sentinel-26381.conf
touch /opt/redis-4.0.10/my_redis_sentinel/sentinel-26382.conf
2. 配置 sentinel-26380.conf 配置文件
- 进入配置文件
vim /opt/redis-4.0.10/my_redis_sentinel/sentinel-26380.conf
- 修改配置文件
# sentinel 端口
port 26380
# 是否后台运行 sentinel,在执行 redis-server redis.conf 命令时,如果为 yes 那么就不进入阻塞状态(即: 还可以输入其他命令),如果为 no 进入阻塞状态 (即: 无法输入别的命令)
daemonize yes
# 日志文件,注意: /data/26380/ 目录必须存在(即: 如果没有就需要手动创建)
logfile "/data/26380/sentinel.log"
# 配置 sentinel 的数据存放文件夹,注意: /data/26380/ 目录必须存在(即: 如果没有就需要手动创建)
dir /data/26380
# 让当前 sentinel 节点监控 10.0.0.3:6380 这个主节点(即:主redis)
# mymaster : 是主节点的别名,可以起别的名字
# 2 : 代表判断主节点(即:主redis)失败(即:宕机)至少需要2个sentinel节点节点同意
sentinel monitor mymaster 10.0.0.3 6380 2
# 当 sentinel 节点集合对主节点(即:主redis)故障判定达成一致时,sentinel领导者节点会做故障转移操作,选出新的主节点(即:主redis),原来的从节点(即:从redis)会向新的主节点(即:主redis)发起复制操作,限制每次向新的主节点(即:主redis)发起复制操作的从节点(即:从redis)个数为1
sentinel parallel-syncs mymaster 1
# 故障转移超时时间为 180000 毫秒
sentinel failover-timeout mymaster 180000
- 创建sentinel配置文件所需要的文件夹
mkdir /data/26380
3. 配置 sentinel-26381.conf 配置文件
- 进入配置文件
vim /opt/redis-4.0.10/my_redis_sentinel/sentinel-26381.conf
- 修改配置文件
# sentinel 端口
port 26381
# 是否后台运行 sentinel,在执行 redis-server redis.conf 命令时,如果为 yes 那么就不进入阻塞状态(即: 还可以输入其他命令),如果为 no 进入阻塞状态 (即: 无法输入别的命令)
daemonize yes
# 日志文件,注意: /data/26381/ 目录必须存在(即: 如果没有就需要手动创建)
logfile "/data/26381/sentinel.log"
# 配置 sentinel 的数据存放文件夹,注意: /data/26381/ 目录必须存在(即: 如果没有就需要手动创建)
dir /data/26381
# 让当前 sentinel 节点监控 10.0.0.3:6380 这个主节点(即:主redis)
# mymaster : 是主节点的别名,可以起别的名字
# 2 : 代表判断主节点(即:主redis)失败(即:宕机)至少需要2个sentinel节点节点同意
sentinel monitor mymaster 10.0.0.3 6380 2
# 当 sentinel 节点集合对主节点(即:主redis)故障判定达成一致时,sentinel领导者节点会做故障转移操作,选出新的主节点(即:主redis),原来的从节点(即:从redis)会向新的主节点(即:主redis)发起复制操作,限制每次向新的主节点(即:主redis)发起复制操作的从节点(即:从redis)个数为1
sentinel parallel-syncs mymaster 1
# 故障转移超时时间为 180000 毫秒
sentinel failover-timeout mymaster 180000
- 创建sentinel配置文件所需要的文件夹
mkdir /data/26381
4. 配置 sentinel-26382.conf 配置文件
- 进入配置文件
vim /opt/redis-4.0.10/my_redis_sentinel/sentinel-26382.conf
- 修改配置文件
# sentinel 端口
port 26382
# 是否后台运行 sentinel,在执行 redis-server redis.conf 命令时,如果为 yes 那么就不进入阻塞状态(即: 还可以输入其他命令),如果为 no 进入阻塞状态 (即: 无法输入别的命令)
daemonize yes
# 日志文件,注意: /data/26382/ 目录必须存在(即: 如果没有就需要手动创建)
logfile "/data/26382/sentinel.log"
# 配置 sentinel 的数据存放文件夹,注意: /data/26382/ 目录必须存在(即: 如果没有就需要手动创建)
dir /data/26382
# 让当前 sentinel 节点监控 10.0.0.3:6380 这个主节点(即:主redis)
# mymaster : 是主节点的别名,可以起别的名字
# 2 : 代表判断主节点(即:主redis)失败(即:宕机)至少需要2个sentinel节点节点同意
sentinel monitor mymaster 10.0.0.3 6380 2
# 当 sentinel 节点集合对主节点(即:主redis)故障判定达成一致时,sentinel领导者节点会做故障转移操作,选出新的主节点(即:主redis),原来的从节点(即:从redis)会向新的主节点(即:主redis)发起复制操作,限制每次向新的主节点(即:主redis)发起复制操作的从节点(即:从redis)个数为1
sentinel parallel-syncs mymaster 1
# 故障转移超时时间为 180000 毫秒
sentinel failover-timeout mymaster 180000
- 创建sentinel配置文件所需要的文件夹
mkdir /data/26382
5. 启动 sentinel(哨兵)
redis-sentinel /opt/redis-4.0.10/my_redis_sentinel/sentinel-26380.conf
redis-sentinel /opt/redis-4.0.10/my_redis_sentinel/sentinel-26381.conf
redis-sentinel /opt/redis-4.0.10/my_redis_sentinel/sentinel-26382.conf
6. 查看sentinel(哨兵)是否启动
ps -ef | grep redis

6. 查看sentinel(哨兵)的状态
redis-cli -p 26380 info sentinel

redis-cli -p 26381 info sentinel

redis-cli -p 26382 info sentinel

redis 故障实验
1. 大致思路
- 结束 主redis进程6380端口,观察从redis是否会进行新的主redis(master)选举,进行切换
- 重新启动旧的 主redis,查看此时 redis 的状态身份
2. 结束主redis进程6380端口
ps -ef | grep redis
kill -9 7411

3. 等待 sentinel 进行主从切换(即: 30秒后查看从redis的身份状态)
4. 查看从redis的身份状态
- 此时查看所有从redis的身份状态,查看是否有一个从reids被设置为了主redis
- 此时 从redis 6381 被设置为了 主redis
redis-cli -p 6381 info replication

- 此时 从redis 6382 的所设置的主redis被给改为 redis 6381
redis-cli -p 6382 info replication

4. 重新启动旧的 主redis,查看此时 redis 的状态身份
- 重新启动旧的 主redis
redis-server /opt/redis-4.0.10/my_redis_sentinel/redis-6380.conf
- 查看此时旧的 主redis 的状态身份
redis-cli -p 6380 info replication

5. 查看此时新主 redis 的状态身份
redis-cli -p 6381 info replication

6. 查 redis 配置文件 和 sentinel 配置文件的变化
- 注意: 当 sentinel 配置文件变化后,原本的注释已经对应不上他的配置项了,所以不要去查看这些注释
- 查 redis 配置文件的变化
vim /opt/redis-4.0.10/my_redis_sentinel/redis-6380.conf

vim /opt/redis-4.0.10/my_redis_sentinel/redis-6381.conf

vim /opt/redis-4.0.10/my_redis_sentinel/redis-6382.conf

- 查 sentinel 配置文件的变化
vim /opt/redis-4.0.10/my_redis_sentinel/sentinel-26380.conf

vim /opt/redis-4.0.10/my_redis_sentinel/sentinel-26381.conf

vim /opt/redis-4.0.10/my_redis_sentinel/sentinel-26382.conf
